// 菜单配置文件
import {treeMap,treeReset} from "@/utils/tree"
import { treeFilter } from "../utils/tree";
// 菜单属性配置，属性映射 key 为目标属性名，value 为原始属性值或者数据处理方法
const props = {
  id:'id',
  index:'path',
  icon:'icon',
  title:'menuLabel',
  disabled:'disabled',
  children:'children',
  show:'show'
}

export const HomePath = '/';

// 菜单数据创建规则 依据 sourceMenu 生成 
// [{path:'',title:'',children:[{title:'',groups:[{path:'',title:'',icon:''}]}]}] 
// 规则如下
// 1. 没有 title 的节点，子节点层级提升，没有子节点则直接忽略
// 3. 对于有 group 的节点，会按照group 的值归类整理，group 对应 el-menu-item-group
// 5. 对于 index ,如果第一个字符不是 / 则继承 父级节点 path 
// 6. 最顶级节点 path 第一个字符必定是 / 如没有，则自动添加

const createTitle = (node) => {
  const cls = [];
  if(node.icon){
    cls.push({tag:'i',class:node.icon})
  }
  if(node.title){
    cls.push({tag:'span',slot:'title',cls:node.title})
  }
  return cls;
}
// 创建 菜单的抽象数据
export const buildMenus = (data) => {
  // 过滤掉 不显示的元素
  data = treeFilter(data,(n) => n.show !== false);
  //
  const ks = Object.keys(props)
  const fn = (item) => {
    const obj = {}
    ks.forEach(k => {
      const v = props[k]
      const t = typeof v;
      if(t === 'string' && Object.prototype.hasOwnProperty.call(item,v)){
        obj[k] = item[v]
      }
      else if(t === 'function'){
        obj[k] = v(item)
      }
    })
    
    return obj;
  }
  //  节点属性重置
  const tree = treeReset(data,fn);
  //
  const mf = (n,list,i,pn,ins) => {
    const {index,title,children = []} = n;
    // 规则一
    if(title == undefined){
      list.splice(i,1,...children)
    }
    // 规则五 + 六
    if(index && index.charAt(0) !== '/'){
      if(pn){
        n.index = pn.index + '/' + n.index
      }else{
        n.index = '/' + n.index;
      }
    }
  }
  // 依据规则修改节点
  const menus = treeMap(tree,mf)
  // 添加元素标签 ， 构造元素内容
  return treeReset(menus,(n) => {
    const obj = {...n}
    if(!obj.tag){
      if(Array.isArray(obj.children) && obj.children.length > 0){
        obj.tag = 'el-submenu'
        obj.children = [...createTitle(obj),...obj.children]
      }else{
        obj.tag = 'el-menu-item'
        obj.cls = createTitle(obj)
      }
    }
    return obj;
  })
}


